#ifndef VECTOR_H
#define VECTOR_H

#include <cmath>
#include <iostream>
#include "constants.h"

class Vector
{
public:
	Vector(const float _x, const float _y, const float _z);
	Vector(const Vector& copy);
	~Vector();

	inline Vector& operator+=(const Vector& v)
	{
		x += v.x;
		y += v.y;
		z += v.z;
		return *this;
	}
	Vector operator~(void) const
	{
		float l = getLength();
		float _x = x;
		float _y = y;
		float _z = z;
		if (l > .0)
		{
			_x /= l;
			_y /= l;
			_z /= l;
		}
		else
		{
			_x = 1.;
			_y = .0;
			_z = .0;
		}
		return Vector(_x, _y, _z);
	}
	inline Vector& operator*=(float m)
	{
		x *= m;
		y *= m;
		z *= m;
		return *this;
	}
	inline Vector& operator/=(float m)
	{
		x /= m;
		y /= m;
		z /= m;
		return *this;
	}
	inline Vector operator*(float m) const
	{
		return Vector(x * m, y * m, z * m);
	}
	inline Vector operator+(const Vector& v) const
	{
		return Vector(x + v.x, y + v.y, z + v.z);
	}
	inline Vector operator-(const Vector& v) const
	{
		return Vector(x - v.x, y - v.y, z - v.z);
	}
	inline Vector operator+(float m) const
	{
		return Vector(x + m, y + m, z + m);
	}
	inline Vector operator/(const Vector& v) const
	{
		return Vector(x / v.x, y / v.y, z / v.z);
	}
	inline Vector operator/(float m) const
	{
		return Vector(x / m, y / m, z / m);
	}
	inline Vector operator-(void) const
	{
		return Vector(-x, -y, -z);
	}

	inline bool operator<(const Vector& v) const
	{
		return getLength() < v.getLength();
	}
	inline bool operator>(const Vector& v) const
	{
		return getLength() > v.getLength();
	}
	inline bool operator<(float d) const
	{
		return getLength() < d;
	}
	inline bool operator>(float d) const
	{
		return getLength() > d;
	}

	friend std::ostream& operator<<(std::ostream& ostr, const Vector& v);

	inline float getLength(void) const
	{
		return sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2));
	}

	inline float get(const int axis) const
	{
		return *((&x) + axis);
	}

	static float dotProduct(const Vector& v1, const Vector& v2);
	static Vector crossProduct(const Vector& v1, const Vector& v2);
	
	float getSigma(void) const;
	float getGamma(void) const;

	float x;
	float y;
	float z;
protected:
private:
};

#endif // VECTOR_H
